/**
 * 请求工具类
 */

// 获取全局设置好的基本请求数据
import {
	HTTP_BASE_URL,
	TOKEN_NAME,
	HEADER,
	SESSION_KEY
} from "@/config/global.js";
import {
	toLogin,
	checkLogin
} from '@/common/libs/login.js';
import Cache from "@/utils/cache.js";
import store from '@/store/index.js';
import upload from "../uni_modules/uview-ui/libs/config/props/upload";
import { message } from "./tools";

// 对请求预处理
function baseDeal(noAuth, url) {
	let header = HEADER;
	
	if (!noAuth) {
		//登录过期自动登录
		if (!store.state.user.token && !checkLogin()) {
			console.log(`${HTTP_BASE_URL + url}跳入：未登录`);
			toLogin();
			return null;
		}
	}
	if (store.state.user.token) header[TOKEN_NAME] = store.state.user.token;
	// 当存在session时,请求头携带session
	let session = Cache.get("session");
	if (session) header[SESSION_KEY] = session;
	
	return header;
}

// 成功响应处理
function successResponse(result, noVerify, isUpload = false) {
	if(result.header) {
		const backSession = result.header["X-Session"] || result.header["x-session"];
		if(backSession) {
			Cache.set("session", backSession);
		}
	}
	
	// 当后台返回二进制流文件时，直接返回一个base64的数据
	if(noVerify) {
		let data = `data:${result.header['content-type']};base64,${uni.arrayBufferToBase64(result.data)}`;
		return {data, ok: true};
	}else {
		const respone = isUpload? JSON.parse(result.data) : result.data;
		const {code, data, message} = respone;
		
		
		if(code >= 200 && code < 300) {
			return {data, ok: true};
		}else if(code >= 400 && code < 500) {
			if(process.env.NODE_ENV === "development") console.error(`${message}`);
			// 当后端返回用户未登录登录时，跳转登录页面
			if(code == 401) return toLogin();
			
			// 其则返回给页面
			return {data, message, ok: false};
		} else if(code >= 500) {
			if(process.env.NODE_ENV === "development") console.error(`服务器错误`);
			return {data, message, ok: false};
		}
		console.error("request无处理");
		return {data, message, ok: false};
	}	
}

// 失败请求处理
function failResponse(msg, url) {
	console.error("请求失败！")
	console.log(`访问${HTTP_BASE_URL + url}`)
	let data = {
		message: "请求失败",
		status: 1 //1没网
	}
	// #ifdef APP-PLUS
	return data;
	// #endif
	// #ifndef APP-PLUS
	return '请求失败！';
	// #endif
}

/**
 * 发送请求
 */
// 八大常用请求
function baseRequest(url, method, data, {
		// 使用需要用户登录才能请求
		noAuth = false,
		// 是否需要过滤请求再返回数据
		noVerify = false
	}, 
	responseType = "text" // 定义返回数据的类型
) {
	
	let Url = HTTP_BASE_URL;
	let	header = baseDeal(noAuth, url);
	
	if(!header) return Promise.reject({
		message: "未登录！"
	});

	return new Promise((reslove, reject) => {
		uni.request({
			url: Url + url,
			method: method || 'GET',
			header: header,
			data: data || {},
			responseType: responseType,
			success: (res) => {
				const result = successResponse(res, noVerify);
				// console.log(result.message)
				// const {message} = result;
				
				if(!result.ok) reject({
								 data: result.data? result.data : {},
								 message: result.message? result.message : ''
								});
				else reslove(result.data? result.data : {});
			},
			fail: (msg) => {
				reject(failResponse(msg, url));
			}
		})
	});
}

function baseUpload(url, key, data, file, {
	// 使用需要用户登录才能请求
	noAuth = false,
	// 是否单文件上传
	isSingle = true,
	// 文件类型
	fileType = 'image',
	// 是否需要过滤请求再返回数据
	noVerify = false
}) {
	if(!url || !key) {
		console.error("上传传递的参数为：" + `
			url, key, data, file, {
				// 使用需要用户登录才能请求
				noAuth = false,
				// 是否单文件上传
				isSingle = true,
				// 文件类型
				fileType = 'image'
			}
			当为多文件上传时file传递的是一个 path数组
		`);
		return Promise.reject({
			message: '参数传递错误'
		}); 
	}
	
	let Url = HTTP_BASE_URL;
	let header = baseDeal(noAuth, url);
	// 判断是否需要携带请求头
	if(!header) return Promise.reject({
		message: '未登录'
	});
	
	// 因为上传之后发送ajax请求之后老是会自动携带Content-Type: 'application/json'，
	// 目前没有发现原因，所以手动处理了
	let dealHeader = {};
	dealHeader[TOKEN_NAME] = store.state.user.token;
	
	return new Promise((resolve, reject) => {
		let uploader = {
			url: Url + url,
			header: dealHeader,
			formData: data,
			name: key,
			timeout: 10000,
			filePath: file
		}
		
		
		uni.uploadFile({
			...uploader,
			success(res) {
				const result = successResponse(res, noVerify, true);
				const {data, message} = result;
				if(!result.ok) reject({data, message, ok: false});
				else if(isSingle) {
					resolve({data, ok: true});
				}else resolve({data, ok: true});
			},
			fail: (msg) => {
				console.log(msg);
				reject(failResponse(msg, url));
			}
		})
	})
}

const request = {};

['options', 'get', 'post', 'put', 'head', 'delete', 'trace', 'connect'].forEach((method) => {
	request[method] = (api, data, opt, responseType) => baseRequest(api, method, data, opt || {}, responseType)
});
// 文件上传
request['upload'] = (url, key, data, file, opt) => baseUpload(url, key, data, file,  opt || {});

export default request;
